﻿using System;
using System.ComponentModel;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using Blackbird.Common.Utility;

namespace Blackbird.Core.Editable.Base {
    public abstract class BaseEditableEntity : IXmlSerializable, IEditableEntity {
        
        
        public abstract string TypeName { get; }

        #region IEditableEntity Members


        private bool _isDirty;
        /// <summary>
        /// Gets the IsDirty  property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool IsDirty  {
            get { return _isDirty; }
            set {
                if (_isDirty == value) {
                    return;
                }
                _isDirty = value;
                InvokePropertyChanged("IsDirty ");
            }
        }

        private bool _isSelected;
        /// <summary>
        /// Gets the IsSelected property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public bool IsSelected {
            get { return _isSelected; }
            set {
                if (_isSelected == value) {
                    return;
                }
                _isSelected = value;
                InvokePropertyChanged("IsSelected");
            }
        }
        
        private string _name;
        public string Name {
            get { return _name; }
            set {
                if (_name != value) {
                    _name = value;
                    InvokePropertyChanged("Name");
                }
            }
        }

        public void Initialize() {

        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region IXmlSerializable Members

        public virtual XmlSchema GetSchema() {
            throw new NotImplementedException();
        }

        public virtual void ReadXml(XmlReader reader) {
            string typeName = GetType().Name;
            if (reader.Name != typeName)
                reader.ReadToFollowing(typeName);
            Name = SerializationUtility.ReadAttribute(reader, "name", "name");
            ReadXmlAttributes(reader);
            reader.ReadStartElement(typeName);
            ReadXmlContent(reader);
            reader.ReadEndElement();
        }

        public virtual void WriteXml(XmlWriter writer) {
            writer.WriteAttributeString("name", Name);
            WriteXmlAttributes(writer);
            WriteXmlContent(writer);
            IsDirty = false;
        }

        #endregion

        protected void InvokePropertyChanged(string propertyName) {
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                IsDirty = true;
            }
        }

        protected abstract void ReadXmlAttributes(XmlReader reader);
        protected abstract void ReadXmlContent(XmlReader reader);

        protected abstract void WriteXmlAttributes(XmlWriter writer);
        protected abstract void WriteXmlContent(XmlWriter writer);
    }
}